package org.loong.crypto.service.core.provider.impl;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.loong.crypto.core.algorithm.MessageDigestAlgorithm;
import org.loong.crypto.service.core.context.CryptoContext;
import org.loong.crypto.service.core.provider.MessageDigestProvider;

/**
 * The base abstract class for message digest.
 * 
 * <p>
 * Supports the following algorithms:
 *
 * <ul>
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#MD5}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SHA1}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SHA224}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SHA256}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SHA384}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SHA512}
 * <li>{@link org.loong.crypto.core.algorithm.MessageDigestAlgorithm#SM3}
 * </ul>
 */
public abstract class BaseMessageDigestProvider implements MessageDigestProvider {

    /**
     * The supported message digest algorithms by the MessageDigest provider class.
     */
    public static final Set<MessageDigestAlgorithm> SUPPORTED_ALGORITHMS;

    /**
     * The cryptoContext.
     */
    private CryptoContext cryptoContext;
    
    static {
        Set<MessageDigestAlgorithm> algs = new LinkedHashSet<>();
        algs.add(MessageDigestAlgorithm.MD5);
        algs.add(MessageDigestAlgorithm.SHA1);
        algs.add(MessageDigestAlgorithm.SHA224);
        algs.add(MessageDigestAlgorithm.SHA256);
        algs.add(MessageDigestAlgorithm.SHA384);
        algs.add(MessageDigestAlgorithm.SHA512);
        algs.add(MessageDigestAlgorithm.SM3);
        SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs);
    }

    @Override
    public Set<MessageDigestAlgorithm> supportedMessageDigestAlgorithms() {
        return SUPPORTED_ALGORITHMS;
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <T extends CryptoContext> T getCryptoContext() {
        return (T) cryptoContext;
    }

    @Override
    public void setCryptoContext(CryptoContext cryptoContext) {
        this.cryptoContext = cryptoContext;
    }
}
